import path from "path";
import fs from "fs";
import express from "express";
import formidable from "formidable";
import { Schema } from "mongoose";
import {
  baseResp,
  reagentModalname,
  reagentSchematype,
  userReagentSchematype,
  userReagentModalname,
} from "../common";
import {
  addData,
  findByPage,
  findByUserPage,
  findAll,
  deleteData,
  deleteUserData,
  updateData,
  updateUserData,
  importData,
  searchreagent,
  searchuserreagent,
  findById,
} from "../mdb/controlDB";
import searchReagentByxmolCas from "../utils/casxmol";
import searchReagentByCas from "../utils/casno";
// import searchReagentByChemsrcCas from "../utils/caschemsrc";

type TReagent = {
  name: string;
  cnname: string;
  formula: string;
  casno: string;
  type: string;
  volatile: boolean;
  viscose: boolean;
  note: string;
  id?: string;
  _id?: string;
  __v?: number;
  density: string;
  mw: string;
  structural: string;
  bp: string;
  mp: string;
  abbreviation: string;
  percentage: number;
};

const reagentschema = new Schema(reagentSchematype);

const userReagentschema = new Schema(userReagentSchematype);

const router = express.Router();

// 根据页码获取所有数据
router.post("/reagentlist", function (req, res) {
  const param = req.body;
  const addback = (data: any, count: any) => {
    let list: any = [];
    data.forEach((item: any) => {
      const {
        casno,
        cnname,
        formula,
        name,
        note,
        type,
        viscose,
        volatile,
        _id,
        density,
        mw,
        structural,
        bp,
        mp,
        abbreviation,
        percentage,
      } = item;
      list.push({
        casno,
        cnname,
        formula,
        name,
        note,
        type,
        viscose,
        volatile,
        id: _id,
        density,
        mw,
        structural,
        bp,
        mp,
        abbreviation,
        percentage,
      });
    });
    res.json(
      Object.assign({}, baseResp, { data: { count, list, page: param.page } })
    );
  };

  findByPage({
    schematype: reagentschema,
    callback: addback,
    modalname: reagentModalname,
    param,
  });

  // addData({
  //   schematype: reagentschema,
  //   callback: addback,
  //   modalname: reagentModalname,
  //   param,
  // });
});

router.post("/userreagentlist", function (req, res) {
  const param = req.body;
  const addback = (data: any, count: any) => {
    let list: any = [];
    data.forEach((item: any) => {
      const {
        casno,
        cnname,
        formula,
        name,
        note,
        type,
        viscose,
        volatile,
        _id,
        density,
        mw,
        structural,
        bp,
        mp,
        abbreviation,
        percentage,
      } = item;
      list.push({
        casno,
        cnname,
        formula,
        name,
        note,
        type,
        viscose,
        volatile,
        id: _id,
        density,
        mw,
        structural,
        bp,
        mp,
        abbreviation,
        percentage,
      });
    });
    res.json(
      Object.assign({}, baseResp, { data: { count, list, page: param.page } })
    );
  };

  findByUserPage({
    schematype: userReagentschema,
    callback: addback,
    modalname: userReagentModalname,
    param,
  });

  // addData({
  //   schematype: reagentschema,
  //   callback: addback,
  //   modalname: reagentModalname,
  //   param,
  // });
});

// 新增数据
router.post("/addreagent", function (req, res) {
  const param = req.body;
  const addback = (data: any) => {
    if (data.success === false) {
      res.json(Object.assign({}, baseResp, data));
    } else {
      res.json(Object.assign({}, baseResp));
    }
  };

  addData({
    schematype: reagentschema,
    callback: addback,
    modalname: reagentModalname,
    param,
  });
});

// 新增用户化学试剂数据
router.post("/adduserreagent", function (req, res) {
  const param = req.body;
  const addback = (data: any) => {
    if (data.success === false) {
      res.json(Object.assign({}, baseResp, data));
    } else {
      res.json(Object.assign({}, baseResp));
    }
  };

  addData({
    schematype: userReagentschema,
    callback: addback,
    modalname: userReagentModalname,
    param,
  });
});

// 编辑试剂
router.post("/updatereagent", (req, res) => {
  const param = req.body;

  const editback = (data: any) => {
    res.json(Object.assign({}, baseResp, { data }));
  };
  updateData({
    schematype: reagentschema,
    callback: editback,
    modalname: reagentModalname,
    param,
  });
});

router.post("/updateuserreagent", (req, res) => {
  const param = req.body;

  const editback = (data: any) => {
    res.json(Object.assign({}, baseResp, { data }));
  };
  updateUserData({
    schematype: userReagentschema,
    callback: editback,
    modalname: userReagentModalname,
    param,
  });
});

// 删除化学试剂
router.post("/delreagent", function (req, res) {
  const param = req.body;
  const delback = (data: any) => {
    res.json(Object.assign({}, baseResp, data));
  };

  deleteData({
    schematype: reagentschema,
    callback: delback,
    modalname: reagentModalname,
    param,
  });
});

router.post("/deluserreagent", function (req, res) {
  const param = req.body;
  const delback = (data: any) => {
    res.json(Object.assign({}, baseResp, data));
  };

  deleteUserData({
    schematype: userReagentschema,
    callback: delback,
    modalname: userReagentModalname,
    param,
  });
});

// 获取所有试剂
router.get("/allreagent", function (req, res) {
  const param = req.body;

  const findback = (data: TReagent[]) => {
    let temp: TReagent[] = [];
    if (data && data.length) {
      data.forEach((item: TReagent) => {
        const {
          name,
          cnname,
          formula,
          casno,
          type,
          volatile,
          viscose,
          note,
          _id,
          density,
          mw,
          structural,
          bp,
          mp,
          abbreviation,
          percentage,
        } = item;
        temp.push({
          name,
          cnname,
          formula,
          casno,
          type,
          volatile,
          viscose,
          note,
          id: _id,
          density,
          mw,
          structural,
          bp,
          mp,
          abbreviation,
          percentage,
        });
      });
    }
    res.json(Object.assign({}, baseResp, { data: temp }));
  };

  findAll({
    schematype: reagentschema,
    callback: findback,
    modalname: reagentModalname,
    param,
  });
});

// 导入化学试剂
router.post("/import", function (req, res) {
  const param = req.body;
  const importback = (data: any) => {
    res.json(Object.assign({}, baseResp, data));
  };

  importData({
    schematype: reagentschema,
    callback: importback,
    modalname: reagentModalname,
    param,
  });
});

// 搜索化学试剂
router.post("/search", function (req, res) {
  const param = req.body;
  const { keyword } = param;
  const searchback = (data: any) => {
    let temp: any = [];
    if (data && data.length) {
      data.forEach((item: TReagent) => {
        const {
          name,
          cnname,
          formula,
          casno,
          type,
          volatile,
          viscose,
          note,
          _id,
          bp,
          mp,
          density,
          mw,
          structural,
          abbreviation,
          percentage,
        } = item;
        temp.push({
          name,
          cnname,
          formula,
          casno,
          type,
          volatile,
          viscose,
          note,
          id: _id,
          bp,
          mp,
          density,
          mw,
          structural,
          abbreviation,
          percentage,
        });
      });
    }
    res.json(Object.assign({}, baseResp, { data: temp }));
  };
  if (keyword) {
    searchreagent({
      schematype: reagentschema,
      callback: searchback,
      modalname: reagentModalname,
      param,
    });
  } else {
    res.json(Object.assign({}, baseResp, { data: [] }));
  }
});

router.post("/searchuser", function (req, res) {
  const param = req.body;
  const { keyword, user } = param;
  const searchback = (data: any) => {
    let temp: any = [];
    if (data && data.length) {
      data.forEach((item: TReagent) => {
        const {
          name,
          cnname,
          formula,
          casno,
          type,
          volatile,
          viscose,
          note,
          _id,
          bp,
          mp,
          density,
          mw,
          structural,
          abbreviation,
          percentage,
        } = item;
        temp.push({
          name,
          cnname,
          formula,
          casno,
          type,
          volatile,
          viscose,
          note,
          id: _id,
          bp,
          mp,
          density,
          mw,
          structural,
          abbreviation,
          percentage,
        });
      });
    }
    res.json(Object.assign({}, baseResp, { data: temp }));
  };
  if (keyword && user) {
    searchuserreagent({
      schematype: userReagentschema,
      callback: searchback,
      modalname: userReagentModalname,
      param,
    });
  } else {
    res.json(Object.assign({}, baseResp, { data: [] }));
  }
});

// 根据id返回化学试剂 searchbyid
router.post("/searchbyid", function (req, res) {
  const param = req.body;
  const { id } = param;

  const searchUserback = (data: any) => {
    let temp: any = [];
    if (data && data.length) {
      data.forEach((item: TReagent) => {
        const {
          name,
          cnname,
          formula,
          casno,
          type,
          volatile,
          viscose,
          note,
          _id,
          bp,
          mp,
          density,
          mw,
          structural,
          abbreviation,
          percentage,
        } = item;
        temp.push({
          name,
          cnname,
          formula,
          casno,
          type,
          volatile,
          viscose,
          note,
          id: _id,
          bp,
          mp,
          density,
          mw,
          structural,
          abbreviation,
          percentage,
        });
      });
    }
    res.json(Object.assign({}, baseResp, { data: temp[0] }));
  };

  const searchback = (data: any) => {
    let temp: any = [];
    if (data && data.length) {
      data.forEach((item: TReagent) => {
        const {
          name,
          cnname,
          formula,
          casno,
          type,
          volatile,
          viscose,
          note,
          _id,
          bp,
          mp,
          density,
          mw,
          structural,
          abbreviation,
          percentage,
        } = item;
        temp.push({
          name,
          cnname,
          formula,
          casno,
          type,
          volatile,
          viscose,
          note,
          id: _id,
          bp,
          mp,
          density,
          mw,
          structural,
          abbreviation,
          percentage,
        });
      });
      res.json(Object.assign({}, baseResp, { data: temp[0] }));
    } else {
      findById({
        schematype: userReagentschema,
        callback: searchUserback,
        modalname: userReagentModalname,
        param,
      });
    }
  };
  if (id) {
    findById({
      schematype: reagentschema,
      callback: searchback,
      modalname: reagentModalname,
      param,
    });
  } else {
    res.json(Object.assign({}, baseResp, { data: [] }));
  }
});

const getInfoByCas = async (casno: string, notMult: boolean) => {
  const data: any = await searchReagentByxmolCas(casno);

  const data2: any = await searchReagentByCas(casno);

  let data3: any = {};
  // if (notMult) {
  //   data3 = await searchReagentByChemsrcCas(casno);
  // }

  if (!data && !data2 && !data3) {
    return null;
  } else {
    let tempObj: any = {
      density: data?.density || data2?.density || data3?.density,
      structural: data?.structural || data2?.structural || data3?.structural,
      mw: data?.mw || data2?.mw || data3?.mw,
      formula: data?.formula || data2?.formula || data3?.formula,
      enname: data?.enname || data2?.enname || data3?.enname,
      cnname: data?.cnname || data2?.cnname || data3?.cnname,
      bp: data?.bp || data2?.bp || data3?.bp,
      mp: data?.mp || data2?.mp || data3?.mp,
    };

    try {
      const { state, isVolatile, isViscose } = data3 || {};
      const { bp, mp } = tempObj;

      // 熔点(mp) > 30 -> pwder
      if (!state) {
        let type = "";
        if (mp && parseFloat(mp) > 30) {
          type = "powder";
        } else {
          type = "liquid";
        }
        tempObj.type = type;
      } else {
        tempObj.type = state;
      }

      // 沸点(bp)<80 -> 易挥发，
      if (isVolatile === -1) {
        let volatile: boolean = false;
        if (bp && parseFloat(bp) < 80) {
          volatile = true;
        }
        tempObj.volatile = volatile;
      } else {
        tempObj.volatile = isVolatile > 0 ? true : false;
      }

      tempObj.viscose = isViscose > 0 ? true : false;
    } catch (e) {}

    return tempObj;
  }
};

router.post("/searchbycas", async function (req, res) {
  const { casno } = req.body;
  const result = await getInfoByCas(casno, true);

  if (result) {
    res.json(Object.assign({}, baseResp, { data: result }));
  } else {
    res.json(Object.assign({}, baseResp, { success: false }));
  }
});

// 上传分子式图片
router.post("/structural", function (req, res, next) {
  const uploadPath = path.join(__dirname, "../../project/images");
  const form = formidable({
    multiples: true,
    uploadDir: uploadPath,
    keepExtensions: true,
  });

  form.parse(req, (err: any, fields: any, files: any) => {
    if (err) {
      next(err);
      return;
    }

    fs.rename(
      path.join(uploadPath, files.structuralup.newFilename),
      path.join(uploadPath, files.structuralup.originalFilename),
      (err) => {
        if (!err) {
          res.json(
            Object.assign({}, baseResp, {
              data: { fileName: files.structuralup.originalFilename },
            })
          );
        }
      }
    );
  });
});

// 批量导入Casno
router.post("/importbycas", async function (req, res) {
  const param = req.body;
  const paramlength = param.length;
  if (paramlength) {
    const resultList: any = [];
    const addAll = (list: any) => {
      let tempList: any = [];
      list.forEach((item: any, index: number) => {
        if (item) {
          const {
            density,
            structural,
            mw,
            formula,
            enname,
            cnname,
            bp,
            mp,
            type,
            volatile,
            viscose,
          } = item;
          tempList.push({
            name: enname,
            cnname,
            formula,
            casno: param[index],
            type,
            volatile,
            viscose,
            note: "",
            density,
            mw,
            structural,
            bp,
            mp,
          });
        }
      });

      importData({
        schematype: reagentschema,
        callback: (data) => {
          res.json(Object.assign({}, baseResp));
        },
        modalname: reagentModalname,
        param: tempList,
      });
    };

    const getAsyncInfo = async (index: number) => {
      const result = await getInfoByCas(param[index], false);
      resultList.push(result);
      index++;
      if (index < paramlength) {
        getAsyncInfo(index);
      } else {
        addAll(resultList);
      }
    };
    getAsyncInfo(0);
  }
});
export default router;
